package com.authine.cloudpivot.web.api.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.authine.cloudpivot.engine.api.facade.TaskReportFacade;
import com.authine.cloudpivot.engine.api.model.bizmodel.BizSchemaModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectQueryModel;
import com.authine.cloudpivot.engine.api.model.runtime.SelectionValue;
import com.authine.cloudpivot.engine.component.query.api.FilterExpression;
import com.authine.cloudpivot.engine.component.query.api.Page;
import com.authine.cloudpivot.engine.component.query.api.helper.PageableImpl;
import com.authine.cloudpivot.engine.component.query.api.helper.Q;
import com.authine.cloudpivot.engine.enums.type.QueryDisplayType;
import com.authine.cloudpivot.web.api.dao.DemandListMapper;
import com.authine.cloudpivot.web.api.dubbo.DubboConfigService;
import com.authine.cloudpivot.web.api.service.RecruitmentService;
import com.authine.cloudpivot.web.api.service.StoreService;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Slf4j
@Service
public class RecruitmentServiceImpl implements RecruitmentService {

    @Reference(version = "1.00")
    private TaskReportFacade taskReportFacade;

    @Autowired
    private DubboConfigService dubboConfigService;

    @Autowired
    private StoreService storeService;

    @Autowired
    private DemandListMapper demandListMapper;

    @Override
    public void createWeeklyReport(String id) {
        //根据id获取招聘需求提报的相关信息
        BizObjectQueryModel queryModel = new BizObjectQueryModel();
        PageableImpl pageable = new PageableImpl(0, 9999);
        queryModel.setSchemaCode("recruitmentDemand");
        queryModel.setQueryCode("recruitmentDemand");
        queryModel.setPageable(pageable);
        FilterExpression filterExpression = Q.it("id", FilterExpression.Op.Eq, id);
        queryModel.setFilterExpr(filterExpression);
        BizObjectQueryModel.Options option = new BizObjectQueryModel.Options();
        option.setQueryDisplayType(QueryDisplayType.APPEND);
        option.setCustomDisplayColumns(Arrays.asList("name","creater","createdDeptId","demandDetails","demandCreatedTime", "demandEndTime","recruitWay","postJD","postJDStr",
                "operator","demandDetails","projectName","recruitmentType","frontOperator","operator","projectNameStr","customCode","subjectPerson"));
        queryModel.setOptions(option);
        Page<BizObjectModel> recruitmentDatas = dubboConfigService.getBizObjectFacade().queryBizObjects(queryModel);

        //更新招聘需求提报时间
        BizObjectModel model = recruitmentDatas.getContent().get(0);
        Map<String, Object> demandData = model.getData();
        String projectName  = (String) ((HashMap<String,Object>)demandData.get("projectName")).get("id");
        List<Map<String, Object>> persons = getMembers(projectName);
        SelectionValue user = ((ArrayList<SelectionValue>) demandData.get("creater")).get(0);
        String userId = user.getId();
        Date now = new Date();
        //demandData.put("demandCreatedTime",now);
        demandData.put("persons",persons);
        demandData.put("name",demandData.get("name"));
        demandData.put("projectNameStr",demandData.get("projectNameStr"));
        BizSchemaModel bizSchemaModel = dubboConfigService.getAppManagementFacade().getBizSchemaBySchemaCode("recruitmentDemand");
        dubboConfigService.getBizObjectFacade().updateBizObjectModel(userId, model, bizSchemaModel);

        //获取所有周报的所有日期以及周期
        List<String> weeklyReportDays = getWeeklyDayTime(demandData);
        List<String> cycles = getCycle(weeklyReportDays);
        List<String> weeklyReportDayList = new ArrayList<>();
        List<String> cycleList = new ArrayList<>();
        LocalDate today = LocalDate.now();
        /*
        String thisMonday = today.with(TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY)).toString();
        String thisSunday = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY )).toString();
        for(int i=0; i<weeklyReportDays.size(); i++){
            if(weeklyReportDays.get(i).compareTo(thisMonday) >=0  && weeklyReportDays.get(i).compareTo(thisSunday) <=0){
                weeklyReportDayList.add(weeklyReportDays.get(i));
                cycleList.add(cycles.get(i));
            }
        }
        */

        String thisMonday = today.with(TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY)).toString();
        for(int i=0; i<weeklyReportDays.size(); i++){
            if(weeklyReportDays.get(i).compareTo(thisMonday) < 0){
                weeklyReportDayList.add(weeklyReportDays.get(i));
                cycleList.add(cycles.get(i));
            }
        }

        createWeekReport(id, userId, weeklyReportDayList, cycleList, demandData, "recruitmentDemand",null);

        //生成周报管理数据
        createReportMgrInfo(id, userId, demandData);
        String recruitmentType = demandData.get("recruitmentType").toString();
        String recruitWay = demandData.get("recruitWay").toString();
        if(!"不确定人数".equals(recruitmentType)) {
            taskReportFacade.updateDemandForById(id, recruitWay);
        }
    }

    @Override
    public  List<Map<String, Object>> getMembers(String projectName) {
        List<Map<String, Object>> persons = new ArrayList<>();
        //根据项目id获取组建团队中的项目专员
        BizObjectQueryModel queryProjectTeamModel = new BizObjectQueryModel();
        PageableImpl projectTeamPage = new PageableImpl(0, 9999);
        queryProjectTeamModel.setSchemaCode("projectTeam");
        queryProjectTeamModel.setQueryCode("projectTeam");
        queryProjectTeamModel.setPageable(projectTeamPage);
        FilterExpression subjectNameFilterExpression = Q.it("subjectName", FilterExpression.Op.Eq, projectName);
        queryProjectTeamModel.setFilterExpr(subjectNameFilterExpression);
        BizObjectQueryModel.Options projectTeamOption = new BizObjectQueryModel.Options();
        projectTeamOption.setQueryDisplayType(QueryDisplayType.APPEND);
        projectTeamOption.setCustomDisplayColumns(Arrays.asList("subjectName", "role"));
        queryProjectTeamModel.setOptions(projectTeamOption);
        Page<BizObjectModel> projectTeamData = dubboConfigService.getBizObjectFacade().queryBizObjects(queryProjectTeamModel);

        projectTeamData.getContent().forEach(
                item->{
                    Map<String, Object> data = item.getData();
                    if(data.get("role") != null  && data.get("member") != null){
                        SelectionValue operator = ((ArrayList<SelectionValue>) data.get("member")).get(0);
                        Map<String, Object> member = new HashMap<>();
                        member.put("id", operator.getId());
                        member.put("type", 3);
                        member.put("name", operator.getName());
                        persons.add(member);
                    }
                }
        );
        return  persons;
    }


    public static List<String> getCycle(List<String> weeklyReportDays) {
        List<String> cycles = new ArrayList<>();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        WeekFields weekFields = WeekFields.ISO;
        weeklyReportDays.forEach(item-> {
            LocalDate date = LocalDate.parse(item, dtf);
            cycles.add("W"+date.get(weekFields.of(DayOfWeek.MONDAY, 1).weekOfMonth()));
        });
        return cycles;
    }

    /**
     *  获取区域时间内 最后每周最后一天,  跨月的周分割成两周月底时间作当月最后一周最后时间
     *   如:2022-6-30 星期四 是6月最后一周最后一天
     *   "2022-06-23" ~ "2022-07-8" 每周最后一天计算出: 2022-06-26,2022-06-30,2022-07-03,2022-07-08
     * @param demandData
     * @return
     */
    public static List<String> getWeeklyDayTime(Map<String, Object> demandData) {
        Date now = (Date) demandData.get("demandCreatedTime");
        Date endTime = (Date) demandData.get("demandEndTime");
        return getWeeklyDayTime(now, endTime);
    }
    public static List<String> getWeeklyDayTime(Date now,Date endTime) {

        String createTimeStr = dateToStr(now);
        String endTimeStr = dateToStr(endTime);
        List<String>  sunDays= getDayOfWeekWithinDateInterval(createTimeStr, endTimeStr, 0);
        List<String> lastDayOfMouths = findLastDayOfMouth(now, endTime);
        sunDays.addAll(lastDayOfMouths);
        return sunDays.stream().distinct().sorted().collect(Collectors.toList());
    }


    //生成周报管理数据
    @Override
    public void createReportMgrInfo(String id, String userId, Map<String, Object> demandData) {
        BizObjectModel bizObjectModel = new BizObjectModel();
        Map<String, Object> data = bizObjectModel.getData();
        if("线上".equals((String) demandData.get("recruitWay"))) {
            bizObjectModel.setSchemaCode("ZPXQZBGL");
            bizObjectModel.setFormCode("ZPXQZBGL");
        }else{
            bizObjectModel.setSchemaCode("XXZPXQZBGL");
            bizObjectModel.setFormCode("XXZPXQZBGL");
        }
        bizObjectModel.setSequenceStatus("COMPLETED");

        SelectionValue frontOperator = ((ArrayList<SelectionValue>) demandData.get("demandReceiver")).get(0);
        Map<String,Object> frontOperatorMap = new HashMap<>();
        frontOperatorMap.put("id",frontOperator.getId());
        frontOperatorMap.put("type",3);
        frontOperatorMap.put("name",frontOperator.getName());
        data.put("frontOperator", Arrays.asList(frontOperatorMap));

        SelectionValue subjectPersonValue = ((ArrayList<SelectionValue>) demandData.get("subjectPerson")).get(0);
        Map<String,Object> subjectPersonMap = new HashMap<>();
        subjectPersonMap.put("id",subjectPersonValue.getId());
        subjectPersonMap.put("type",3);
        subjectPersonMap.put("name",subjectPersonValue.getName());
        List<Map<String, Object>> subjectPerson = Arrays.asList(subjectPersonMap);
        data.put("subjectPerson", subjectPerson);

        if(demandData.get("operator")==null){
            data.put("operator", null);
        }else{
            SelectionValue operator = ((ArrayList<SelectionValue>) demandData.get("operator")).get(0);
            Map<String,Object> operatorMap = new HashMap<>();
            operatorMap.put("id",operator.getId());
            operatorMap.put("type",3);
            operatorMap.put("name",operator.getName());
            data.put("operator", Arrays.asList(operatorMap));
        }


        data.put("customCode",demandData.get("customCode"));
        String postNature = ((ArrayList<HashMap<String,Object>>)demandData.get("demandDetails")).get(0).get("jobNature").toString();
        data.put("postNature", postNature);
        data.put("subject", demandData.get("projectName"));
        data.put("recruitmentDemand", id);
        Map<String,Object> departMap = new HashMap<>();
        departMap.put("id",((ArrayList<SelectionValue>) demandData.get("createdDeptId")).get(0).getId());
        departMap.put("type",1);
        data.put("depart", Arrays.asList(departMap));
        data.put("postJD", demandData.get("postJD"));
        data.put("demandCreatedTime",demandData.get("demandCreatedTime"));
        data.put("recruitmentType",demandData.get("recruitmentType"));
        //data.put("demandFor", totalDemandFor);
        data.put("persons", demandData.get("persons"));
        data.put("needFinishTime",demandData.get("demandEndTime"));
        data.put("projectNameStr",demandData.get("projectNameStr"));
        data.put("postJDStr",demandData.get("postJDStr"));
        dubboConfigService.getBizObjectFacade().saveBizObject(userId, bizObjectModel, true);
    }

    @Override
    public Integer updateDemandDetailList(String id) {
        Integer count1 = demandListMapper.updateCancel(id);
        Integer count2 = demandListMapper.updateFinished(id);
        return count1 + count2;
    }

    @Override
    public void createWeekReport(String id, String userId,List<String> weeklyReportDays, List<String>cycles, Map<String, Object> demandData,String schemaCode, Date[] stateModifiedTimeRegion) {
        List<Map<String, Object>> demandDetails = null;
        SelectionValue subjectPersonValue = ((ArrayList<SelectionValue>) demandData.get("subjectPerson")).get(0);
        Map<String,Object> subjectPersonMap = new HashMap<>();
        subjectPersonMap.put("id",subjectPersonValue.getId());
        subjectPersonMap.put("type",3);
        subjectPersonMap.put("name",subjectPersonValue.getName());
        List<Map<String, Object>> subjectPerson = Arrays.asList(subjectPersonMap);

        if("recruitmentDemand".equals(schemaCode)) {
            demandDetails = (ArrayList<Map<String, Object>>) demandData.get("demandDetails");
        }else{
            demandDetails =(ArrayList<Map<String, Object>>) demandData.get("demandDetailList");
            demandDetails = demandDetails.stream().filter(item-> item.get("needCreateReport") != null).collect(Collectors.toList());
        }
        if(demandDetails != null && demandDetails.size() > 0) {
            SelectionValue user = ((ArrayList<SelectionValue>) demandData.get("creater")).get(0);
            SelectionValue depart = ((ArrayList<SelectionValue>) demandData.get("createdDeptId")).get(0); // String deptName = ((ArrayList<SelectionValue>) demandData.get("createdDeptId")).get(0).getName();
            Map<String, Object> departMap = new HashMap<>();
            departMap.put("id", depart.getId());
            departMap.put("type", 1);
            departMap.put("name", depart.getName());
            String projectName = (String) ((HashMap<String, Object>) demandData.get("projectName")).get("id");
            String postName = (String) ((HashMap<String, Object>) demandData.get("postJD")).get("id");
            String postJDStr = (String) ((HashMap<String, Object>) demandData.get("postJD")).get("jobName");
            Date demandCreatedTime = (Date) demandData.get("demandCreatedTime");
            String projectNameStr = (String) demandData.get("projectNameStr");
            Date needFinishTime = (Date) demandData.get("demandEndTime");
            String recruitWay = (String) demandData.get("recruitWay");
            AtomicInteger integer = new AtomicInteger(0);

            String recruitmentType = MapUtils.getString(demandData, "recruitmentType", "");

            List<Map<String, Object>> finalDemandDetails = demandDetails;
            weeklyReportDays.forEach(item -> {
                String[] dateStr = item.split("-");
                String year = dateStr[0];
                String month = dateStr[1];
                int index = integer.getAndIncrement();

                finalDemandDetails.forEach(detail -> {

                    String state = (String) detail.get("state");
                    if(!"进行中".equals(state)){
                        //状态有可能是通过 变更和关闭流程 修改的(记录状态修改时间), 这种情况下当周的 日报定时任务还需生成
                        if (stateModifiedTimeRegion != null && stateModifiedTimeRegion.length==2) {
                            Date stateModifiedTime = (Date) detail.get("stateModifiedTime");
                            //状态修改时间为null  或者 不在本周时间区间中 就不生成周报
                            if (stateModifiedTime ==null || stateModifiedTime.before(stateModifiedTimeRegion[0]) || stateModifiedTime.after(stateModifiedTimeRegion[1])){
                                return;
                            }
                        }else {
                            return;
                        }
                    }
                    if ("按确定人数".equals(recruitmentType)){
                        Integer demandFor = MapUtils.getInteger(detail, "demandFor", 0);
                        Integer hasHiredNum = MapUtils.getInteger(detail, "hasHiredNum", 0);
                        // 需求数等于0 或者 等于已入职数, 就不用生成周报了
                        if (demandFor.intValue()==0 || demandFor.intValue()==hasHiredNum.intValue()){
                            return;
                        }
                    }


                    //新增周报信息
                    BizObjectModel bizObjectModel = new BizObjectModel();
                    Map<String, Object> data = bizObjectModel.getData();
                    if ("线上".equals(recruitWay)) {
                        bizObjectModel.setSchemaCode("XSZPZBTJ");
                        bizObjectModel.setFormCode("XSZPZBTJ");
                        data.put("communicateNum",0);
                        data.put("inviteNum",0);
                        data.put("toFaceNum",0);
                        data.put("offerNum",0);
                        data.put("entryNum",0);
                        data.put("clientProvideNum",0);
                        data.put("projectProvideNum",0);

                    } else {
                        bizObjectModel.setSchemaCode("XXZPZBTJ");
                        bizObjectModel.setFormCode("XXZPZBTJ");
                    }
                    bizObjectModel.setSequenceStatus("COMPLETED");
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                    String createdTime = null;
                    try {
                        Date date = sdf.parse(item + " 23:59:59");
                        createdTime = DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss");
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    data.put("subjectPerson", subjectPerson);
                    data.put("postId", detail.get("idCode"));
                    data.put("year", year);
                    data.put("month", month);
                    data.put("depart", Arrays.asList(departMap));

                    Map<String, Object> userMap = new HashMap<>();
                    userMap.put("id", user.getId());
                    userMap.put("type", 3);
                    userMap.put("name", user.getName());
                    data.put("customCode", detail.get("customCode"));
                    data.put("frontOperator", Arrays.asList(userMap));
                    data.put("demandCreatedTime", demandCreatedTime);
                    data.put("reportCreateTime", createdTime);
                    data.put("projectName", projectName);
                    data.put("postJDStr", postJDStr);
                    data.put("storeCode", detail.get("storeCode"));
                    data.put("province", detail.get("province"));
                    data.put("city", detail.get("city"));
                    data.put("areas", detail.get("areas"));
                    data.put("area", detail.get("area"));
                    data.put("storeName", detail.get("storeName"));
                    data.put("address", detail.get("address"));
                    data.put("jobName", postName);
                    data.put("postNature", detail.get("jobNature"));
                    data.put("recruitmentType", detail.get("workType"));
                    data.put("demandFor", detail.get("demandFor"));
                    data.put("needFinishTime", needFinishTime);
                    data.put("rcsArea", detail.get("rcsArea"));
                    data.put("projectNameStr", projectNameStr);
                    data.put("persons", demandData.get("persons"));
                    data.put("cycle", cycles.get(index));
                    if ("线上".equals(recruitWay)) {
                        data.put("state", "未提交");
                        data.put("isModifiable", "否");
                    } else {
                        data.put("state", "未提交");
                        data.put("isModifiable", "是");
                    }
                    data.put("isPigeonholed", "未归档");
                    data.put("recuitmentId", id);
                    data.put("atsId", detail.get("atsId"));

                    if ("线上".equals(recruitWay)) {
                        if (demandData.get("operator") != null) {
                            SelectionValue operator = ((ArrayList<SelectionValue>) demandData.get("operator")).get(0);
                            Map<String, Object> PurchaseMap = new HashMap<>();
                            PurchaseMap.put("id", operator.getId());
                            PurchaseMap.put("type", 3);
                            PurchaseMap.put("name", operator.getName());
                            data.put("operator", Arrays.asList(PurchaseMap));
                        }
                    } else {
                        if (demandData.get("operator") != null) {
                            SelectionValue operator = ((ArrayList<SelectionValue>) demandData.get("operator")).get(0);
                            Map<String, Object> PurchaseMap = new HashMap<>();
                            PurchaseMap.put("id", operator.getId());
                            PurchaseMap.put("type", 3);
                            PurchaseMap.put("name", operator.getName());
                            data.put("operator", Arrays.asList(PurchaseMap));
                        }
                    }
                    dubboConfigService.getBizObjectFacade().saveBizObject(userId, bizObjectModel, false);

                });
            });

            //for(int i=0; i< demandDetails.size(); i++){
            //    total = total.add((BigDecimal) demandDetails.get(i).get("demandFor"));
            //}
        }
        //return total;
    }

    @Override
    public void closeWeeklyReport(String id) {
        //根据id获取招聘需求提报的相关信息
        BizObjectQueryModel queryModel = new BizObjectQueryModel();
        PageableImpl pageable = new PageableImpl(0, 9999);
        queryModel.setSchemaCode("recruitmentDemand");
        queryModel.setQueryCode("recruitmentDemand");
        queryModel.setPageable(pageable);
        FilterExpression filterExpression = Q.it("id", FilterExpression.Op.Eq, id);
        queryModel.setFilterExpr(filterExpression);
        BizObjectQueryModel.Options option = new BizObjectQueryModel.Options();
        option.setQueryDisplayType(QueryDisplayType.APPEND);
        option.setCustomDisplayColumns(Arrays.asList("creater","createdDeptId","demandDetails","demandCreatedTime","demandEndTime","recruitWay","postJD","projectNameStr","idCode"));
        queryModel.setOptions(option);
        Page<BizObjectModel> recruitmentDatas = dubboConfigService.getBizObjectFacade().queryBizObjects(queryModel);
        List<Map<String,Object>> demandDetails = (ArrayList<Map<String,Object>>)recruitmentDatas.getContent().get(0).getData().get("demandDetails");
        Date currentSunday = getCurrentSunday();
        if(demandDetails != null && demandDetails.size() > 0) {
            String recruitWay = (String)recruitmentDatas.getContent().get(0).getData().get("recruitWay");
            if("线上".equals(recruitWay)) {
                taskReportFacade.delOnLineReport(currentSunday, id);
            }else{
                taskReportFacade.delOffLineReport(currentSunday, id);
            }
        }
    }

    @Override
    public void updateStoreState(String id, String state) {
        //将子表中门店信息状态设置为已取消
        taskReportFacade.updateStoreState(id,state);
    }

    @Override
    public void updateRecruitmentDemand(String id) {
        //招聘需求变更信息
        BizObjectQueryModel queryModel = new BizObjectQueryModel();
        PageableImpl pageable = new PageableImpl(0, 9999);
        queryModel.setSchemaCode("recruitmentDemandUpdate");
        queryModel.setQueryCode("recruitmentDemandUpdate");
        queryModel.setPageable(pageable);
        FilterExpression filterExpression = Q.it("id", FilterExpression.Op.Eq, id);
        queryModel.setFilterExpr(filterExpression);
        BizObjectQueryModel.Options option = new BizObjectQueryModel.Options();
        option.setQueryDisplayType(QueryDisplayType.APPEND);
        option.setCustomDisplayColumns(Arrays.asList("copyDemand","demandEndTime","demandDetailList","requirementDesc","wagesTime","paydayFrequency","msInstance","zpFee","zpCycle",
                "feedbackFrequency","contractFS","contractDeline","desc","signatory","demandReceiver","recruitWay","recruitmentType","creater","projectName",
                "postJD","createdDeptId","demandCreatedTime","projectNameStr","subjectPerson"));
        queryModel.setOptions(option);
        Map<String, Object> updatedDemandData = dubboConfigService.getBizObjectFacade().queryBizObjects(queryModel).getContent().get(0).getData();
        String recruitmentId = (String)((HashMap<String, Object>)updatedDemandData.get("copyDemand")).get("id");
        Date newDemandTime =  (Date) updatedDemandData.get("demandEndTime");
        SelectionValue user = ((ArrayList<SelectionValue>)  updatedDemandData.get("creater")).get(0);
        String userId = user.getId();
        //更新门店需求数量
        List<Map<String, Object>> demandDetails = (ArrayList<Map<String, Object>>)updatedDemandData.get("demandDetailList");

        //String recruitWay =  (String) updatedDemandData.get("recruitWay");
        String recruitmentType = (String) updatedDemandData.get("recruitmentType");
        if("不确定人数".equals(recruitmentType)){
            List<Map<String,Object>> unContainsIdCode = demandDetails.stream().filter(item -> item.get("idCode")  == null ||StringUtils.isBlank(item.get("idCode").toString())).collect(Collectors.toList());
            unContainsIdCode.forEach(
                    item->{
                        Map<String, Object> data = new HashMap<>();
                        String uuid = UUID.randomUUID().toString().replace("-", "");
                        data.put("recruitmentId", recruitmentId);
                        data.put("storeCode", item.get("storeCode"));
                        data.put("province", item.get("province"));
                        data.put("areas", item.get("areas"));
                        data.put("city", item.get("city"));
                        data.put("storeName", item.get("storeName"));
                        data.put("address", item.get("address"));
                        data.put("rcsArea", item.get("rcsArea"));
                        data.put("area", item.get("area"));
                        data.put("storeChannel", item.get("storeChannel"));
                        data.put("storeContacts", item.get("storeContacts"));
                        data.put("contactsPhone", item.get("contactsPhone"));
                        data.put("cityType", item.get("cityType"));
                        data.put("workType", item.get("workType"));
                        data.put("isFixedWorkPlace", "是");
                        data.put("isStore", "是");

                        data.put("jobNature", item.get("jobNature"));
                        data.put("scale", item.get("scale"));
                        data.put("salaryCap", item.get("salaryCap"));
                        data.put("contractType", item.get("contractType"));
                        data.put("probationaryTime", item.get("probationaryTime"));
                        data.put("probationarySalary", item.get("probationarySalary"));
                        data.put("comment", item.get("comment"));
                        data.put("idCode",  item.get("storeCode").toString() +"_"+uuid);
                        data.put("demandFor", item.get("demandFor"));

                        data.put("modifier", user.getId());
                        data.put("modifiedTime", new Date());
                        data.put("state","进行中");
                        data.put("id", uuid);
                        taskReportFacade.createRecruitmentDetail(data);
                        item.put("recruitmentId", recruitmentId);
                        item.put("idCode", item.get("storeCode").toString() +"_"+uuid);
                        item.put("isFixedWorkPlace", "是");
                        item.put("isStore", "是");
                        item.put("id", uuid);
                        item.put("needCreateReport",true);
                    }
            );
        }
        List<String> cancelIdCodes = new ArrayList<>();
        List<String> underWayIdCodes = new ArrayList<>();

        List<Map<String,Object>> containsIdCode = demandDetails.stream().filter(item -> item.get("idCode") != null).collect(Collectors.toList());
        containsIdCode.forEach(item->{
                String idCode = (String)item.get("idCode");
                BigDecimal newDemandFor = (BigDecimal) item.get("newDemandFor");
                String storeContacts =  (String)item.get("storeContacts");
                String contactsPhone =  (String)item.get("contactsPhone");
                String comment =  (String)item.get("comment");
                if(newDemandFor!= null && newDemandFor.intValue() == 0 ){
                    cancelIdCodes.add(idCode);
                }else{
                    underWayIdCodes.add(idCode);
                }

                taskReportFacade.updateDemandFor(recruitmentType, idCode, newDemandFor, storeContacts, contactsPhone, comment);
            }
        );

        //如果门店新需求数为0，将子表中门店的状态设置成已取消
        if(!"不确定人数".equals(recruitmentType)){
            taskReportFacade.updateRecruitmentDetailStatus(cancelIdCodes,"进行中");
        } else if(CollectionUtils.isNotEmpty(cancelIdCodes) && !"不确定人数".equals(recruitmentType)) {
            taskReportFacade.updateRecruitmentDetailStatus(cancelIdCodes,"已取消");
        }

        //如果门店新需求数大于0，将子表中门店的状态设置成进行中（为了将已取消的门店变成进行中）
        if(CollectionUtils.isNotEmpty(underWayIdCodes) && !"不确定人数".equals(recruitmentType)) {
            taskReportFacade.updateRecruitmentDetailStatus(underWayIdCodes,"进行中");
        }

        //将招聘需求提报子表中的门店信息表
        storeService.addStore(recruitmentId);

        //更新招聘需求信息
        //根据id获取招聘需求提报的相关信息
        BizObjectQueryModel queryRecruitmentModel = new BizObjectQueryModel();
        queryRecruitmentModel.setSchemaCode("recruitmentDemand");
        queryRecruitmentModel.setQueryCode("recruitmentDemand");
        queryRecruitmentModel.setPageable(pageable);
        FilterExpression idFilterExpression = Q.it("id", FilterExpression.Op.Eq, recruitmentId);
        queryRecruitmentModel.setFilterExpr(idFilterExpression);
        BizObjectQueryModel.Options recruitOption = new BizObjectQueryModel.Options();
        recruitOption.setQueryDisplayType(QueryDisplayType.APPEND);
        recruitOption.setCustomDisplayColumns(Arrays.asList("copyDemand","demandEndTime","wagesTime","paydayFrequency","msInstance","zpFee","zpCycle",
                "feedbackFrequency","contractFS","contractDeline","desc","signatory","recruitWay","demandDetails", "creater","createdDeptId","demandCreatedTime","postJD",
                "projectNameStr","operator","projectName","recruitmentType","demandReceiver","projectNameStr","recruitmentType"));
        queryRecruitmentModel.setOptions(recruitOption);
        BizObjectModel bizObjectModel = dubboConfigService.getBizObjectFacade().queryBizObjects(queryRecruitmentModel).getContent().get(0);
        //Date oldDemandTime =  (Date) bizObjectModel.getData().get("demandEndTime");

        Map<String, Object> demandData = bizObjectModel.getData();
        SelectionValue demandReceiver = ((ArrayList<SelectionValue>) updatedDemandData.get("demandReceiver")).get(0);
        Map<String,Object> demandReceiverMap = new HashMap<>();
        demandReceiverMap.put("id",demandReceiver.getId());
        demandReceiverMap.put("type",3);
        demandReceiverMap.put("name",demandReceiver.getName());
        demandData.put("demandReceiver", Arrays.asList(demandReceiverMap));
        demandData.put("demandEndTime",updatedDemandData.get("demandEndTime"));
        demandData.put("wagesTime",updatedDemandData.get("wagesTime"));
        demandData.put("paydayFrequency",updatedDemandData.get("paydayFrequency"));
        demandData.put("msInstance",updatedDemandData.get("msInstance"));
        demandData.put("zpFee",updatedDemandData.get("zpFee"));
        demandData.put("zpCycle",updatedDemandData.get("zpCycle"));
        demandData.put("feedbackFrequency",updatedDemandData.get("feedbackFrequency"));
        demandData.put("contractFS",updatedDemandData.get("contractFS"));
        demandData.put("contractDeline",updatedDemandData.get("contractDeline"));
        demandData.put("desc",updatedDemandData.get("desc"));
        demandData.put("signatory",updatedDemandData.get("signatory"));
        demandData.put("projectNameStr",updatedDemandData.get("projectNameStr"));
        demandData.put("requirementDesc",updatedDemandData.get("requirementDesc"));
        demandData.put("stateModifiedTime",new Date());
        BizSchemaModel bizSchemaModel = dubboConfigService.getAppManagementFacade().getBizSchemaBySchemaCode("recruitmentDemand");
        dubboConfigService.getBizObjectFacade().updateBizObjectModel(userId, bizObjectModel, bizSchemaModel);

        //TODO 处理周报
        updateReportInfo(userId, updatedDemandData, newDemandTime,  recruitmentId);

        //如果门店新需求数为0，删除本周末以后的周报
        //String recruitWay =  (String) demandData.get("recruitWay");
        //delReportInfo(recruitWay, idCodes);
    }

    //private void delReportInfo(String recruitWay, List<String> idCodes) {
    //    if(CollectionUtils.isNotEmpty(idCodes)) {
    //
    //       taskReportFacade.delReportInfoByICode(recruitWay, idCodes, getNextMonday());
    //    }
    //}

    public static Date getNextMonday(){
        LocalDateTime nextMonday = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).plusWeeks(1).with(DayOfWeek.MONDAY);
        //周一（第一天）
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = nextMonday.atZone(zone).toInstant();
        Date dateime = Date.from(instant);
        return Date.from(instant);
    }

    private void updateReportInfo(String userId, Map<String, Object> demandData, Date newDemandTime,  String recruitmentId) {
        String projectName  = (String) ((HashMap<String,Object>)demandData.get("projectName")).get("id");
        List<Map<String, Object>> persons = getMembers(projectName);
        demandData.put("persons",persons);

        //新增周报
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //String newDate = sdf.format(newDemandTime);       //将Date类型转换成String类型
        //String oldDate = sdf.format(oldDemandTime);

        String recruitWay =  (String) demandData.get("recruitWay");
        String recruitmentType = (String) demandData.get("recruitmentType");
        ArrayList<Object[]> reportCreateTimeList = taskReportFacade.getReportCreateTimeList(recruitmentId, recruitWay);
        demandData.put("demandEndTime",newDemandTime);
        List<String> weeklyReportDays = getWeeklyDayTime(demandData);
        List<String> cycles = getCycle(weeklyReportDays);
        List<String> newWeeklyReportDays = new ArrayList<>();
        List<String> newCycles = new ArrayList<>();

        Set<String> reportCreateDateSet = reportCreateTimeList.stream().map(item -> item[1].toString()).collect(Collectors.toSet());
        Set<String> weeklyReportDaysSet = new HashSet<>(weeklyReportDays);
        //需要删除的日报
        List <String> delSet= new ArrayList<>(Sets.difference(reportCreateDateSet, weeklyReportDaysSet));
        List<String> delIds = reportCreateTimeList.stream().filter(item -> delSet.contains(item[1].toString())).map(item -> item[0].toString()).collect(Collectors.toList());
        //需要新增的日报
        LocalDate today = LocalDate.now();
        String thisMonday = today.with(TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY)).toString();
        for (int i = 0; i < weeklyReportDays.size(); i++) {
            if(weeklyReportDays.get(i).compareTo(thisMonday) < 0){
                newWeeklyReportDays.add(weeklyReportDays.get(i));
                newCycles.add(cycles.get(i));
            }
        }

        /*
        LocalDate today = LocalDate.now();
        String thisMonday = today.with(TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY)).toString();
        String thisSunday = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY )).toString();
        for (int i = 0; i < weeklyReportDays.size(); i++) {
            if(weeklyReportDays.get(i).compareTo(thisMonday) >=0  && weeklyReportDays.get(i).compareTo(thisSunday) <=0){
                newWeeklyReportDays.add(weeklyReportDays.get(i));
                newCycles.add(cycles.get(i));
            }
        }
        */
        //删除周报
        if(!delIds.isEmpty()) {
            taskReportFacade.delWeeklyReport(delIds, recruitWay);
        }

        //新增周报
        createWeekReport(recruitmentId, userId, newWeeklyReportDays,newCycles, demandData,"recruitmentDemandUpdate",null);

        //更新未归档的招聘周报的需求数和完成时间
        taskReportFacade.updateWeeklyReportInfo(recruitmentId,newDemandTime,recruitWay);

        //更新招聘管理数据的总需求数和完成时间
        taskReportFacade.updateWeeklyReportMgrInfo(recruitmentId,newDemandTime,recruitWay,recruitmentType);
    }


    @Override
    public List<Map<String,Object>> getRecruimentStores(String id) {
        //根据id获取招聘需求提报的相关信息
        BizObjectQueryModel queryModel = new BizObjectQueryModel();
        PageableImpl pageable = new PageableImpl(0, 9999);
        queryModel.setSchemaCode("recruitmentDemand");
        queryModel.setQueryCode("recruitmentDemand");
        queryModel.setPageable(pageable);
        FilterExpression filterExpression = Q.it("id", FilterExpression.Op.Eq, id);
        queryModel.setFilterExpr(filterExpression);
        BizObjectQueryModel.Options option = new BizObjectQueryModel.Options();
        option.setQueryDisplayType(QueryDisplayType.APPEND);
        option.setCustomDisplayColumns(Arrays.asList("demandDetails"));
        queryModel.setOptions(option);
        Page<BizObjectModel> recruitmentDatas = dubboConfigService.getBizObjectFacade().queryBizObjects(queryModel);
        List<Map<String,Object>> demandDetails = (ArrayList<Map<String,Object>>)recruitmentDatas.getContent().get(0).getData().get("demandDetails");
        return demandDetails;
    }

    @Override
    public void updateRecruitmentState(String id, String state) {
        //更新招聘需求状态
        taskReportFacade.updateRecruitmentState(id,state);
    }


    public static Date getCurrentSunday(){
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式
        Calendar cld = Calendar.getInstance(Locale.CHINA);
        cld.setFirstDayOfWeek(Calendar.MONDAY);//以周一为首日
        cld.setTimeInMillis(System.currentTimeMillis());//当前时间
        cld.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);//周日

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = sdf.parse(df.format(cld.getTime()) + " 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }


    public static String dateToStr(Date dateDate) {
           SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String dateString = formatter.format(dateDate);
           return dateString;
    }


    /**
     * 获取某段时间内的周一（二等等）的日期
     * @param dataBegin 开始日期
     * @param dataEnd 结束日期
     * @param weekDays 获取周几，1－6代表周一到周六。0代表周日
     * @return 返回日期List
     */
    public static List<String> getDayOfWeekWithinDateInterval(String dataBegin, String dataEnd, int weekDays) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> dateResult = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        String[] dateInterval = {dataBegin, dataEnd};
        Date[] dates = new Date[dateInterval.length];
        for (int i = 0; i < dateInterval.length; i++) {
            String[] ymd = dateInterval[i].split("[^\\d]+");
            cal.set(Integer.parseInt(ymd[0]), Integer.parseInt(ymd[1]) - 1, Integer.parseInt(ymd[2]));
            dates[i] = cal.getTime();
        }
        for (Date date = dates[0]; date.compareTo(dates[1]) <= 0; ) {
            cal.setTime(date);
            if (cal.get(Calendar.DAY_OF_WEEK) - 1 == weekDays) {
                String format = sdf.format(date);
                dateResult.add(format);
            }
            cal.add(Calendar.DATE, 1);
            date = cal.getTime();
        }
        return dateResult;
    }


    /**
     * 获取某段时这里写代码片间内的所有日期
     *  获取区域时间内每个月最后一天日期
     *
     * @param dBegin
     * @param dEnd
     * @return
     */
    public static List<String> findLastDayOfMouth(Date dBegin, Date dEnd) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> lDate = new ArrayList<>();
        //lDate.add(simpleDateFormat.format(dBegin));
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        // 测试此日期是否在指定日期之后

        Calendar calBegin_1 = (Calendar) calBegin.clone();
        //把月底提出来
        calBegin_1.add(Calendar.MONDAY,1);
        calBegin_1.set(Calendar.DAY_OF_MONTH,0);

        boolean endMouth = false;
        while (dEnd.after(calBegin.getTime())) {
            if (calBegin_1.equals(calBegin) || endMouth){
                //保存最后一天
                lDate.add(simpleDateFormat.format(calBegin.getTime()));

                //保存第一天
                calBegin.add(Calendar.MONTH, 1);
                calBegin.set(Calendar.DAY_OF_MONTH,1);
                //lDate.add(simpleDateFormat.format(calBegin.getTime()));

                calBegin.add(Calendar.MONDAY,1);
                calBegin.set(Calendar.DAY_OF_MONTH,0);

                endMouth = true;

            }else {
//                calBegin.add(Calendar.DAY_OF_MONTH,1);
                calBegin.add(Calendar.MONDAY,1);
                calBegin.set(Calendar.DAY_OF_MONTH,0);
            }
        }
        lDate.add(simpleDateFormat.format(dEnd));

        return lDate;
    }

}
